package com.goldsprite.contourextraction.examples;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.utils.ScreenUtils;
import com.badlogic.gdx.utils.viewport.FitViewport;
import com.goldsprite.contourextraction.core.*;

import java.util.ArrayList;
import java.util.List;

public class GdxLauncher extends ApplicationAdapter {
	private SpriteBatch batch;
	private ShapeRenderer shapeRenderer;
	private Texture grassTexture, rotatedTexture;

	private int curOptionIndex = 0;
	Object[][] options = {
		{"role_500x.png", 0.9f, 1.0f},
		{"testImage2.png", 12f, 1.2f},
		{"testImage3.png", 15f, 1.2f},
		{"testImage.png", 10f, 1.5f},
	};

	private String imagePath = (String) options[curOptionIndex][0];
	private float scale = (float) options[curOptionIndex][1]; // 图片缩放比例
	private float polygonWidth = (float) options[curOptionIndex][2];
	private Color polygonColor = Color.valueOf("#FF6B6B80"); // 半透明红色
	private Color backgroundColor = Color.valueOf("#AAAAAA");

	private Color clearColor = Color.valueOf("#333333FF");
//	private Color polygonColor = Color.valueOf("#0000FF");

	float worldWidth = 960, worldHeight = 540;
	private FitViewport worldViewport;
	private OrthographicCamera cam;

	private List<Contour> contours;
	private boolean contoursExtracted = false;
	private List<float[]> contourVerticesList;
	private int[][] imageData;
	private float rotation = 0;

	private int curState = 0;
	private String[] states = {
		"rotateImage", "extractContour", "convexHull"
	};

	@Override
	public void create() {
		shapeRenderer = new ShapeRenderer();
		batch = new SpriteBatch();

		// 加载grass.png纹理
		grassTexture = new Texture(Gdx.files.internal(imagePath));
		imageData = extractAndRotateImageDataFromTexture();

		worldViewport = new FitViewport(worldWidth, worldHeight);
	}

	@Override
	public void render() {
		ScreenUtils.clear(clearColor);

		worldViewport.apply(true);

		// 绘制背景
		shapeRenderer.setProjectionMatrix(worldViewport.getCamera().combined);
		shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
		shapeRenderer.setColor(backgroundColor);
		shapeRenderer.rect(0, 0, worldWidth, worldHeight);
		shapeRenderer.end();

		// 绘制grass图像
		batch.setProjectionMatrix(worldViewport.getCamera().combined);
		batch.begin();
		{
			float textureWidth = rotatedTexture.getWidth() * scale;
			float textureHeight = rotatedTexture.getHeight() * scale;
			float centerX = (worldWidth - textureWidth) / 2;
			float centerY = (worldHeight - textureHeight) / 2;

			batch.draw(rotatedTexture, centerX, centerY, textureWidth, textureHeight);
		}
		batch.end();

		// 如果已提取轮廓，绘制半透明多边形
		if (contoursExtracted && contours != null && !contours.isEmpty()) {
			drawContourPolygons();
		}

		// 处理点击事件
		if (Gdx.input.justTouched()) {
			curState = ++curState % states.length;
			switch (states[curState]) {
				case "rotateImage":
					float step = 45;
					rotation = (rotation + step) % 360;
					imageData = extractAndRotateImageDataFromTexture();
					break;
				case "extractContour":
					extractContours(false);
					break;
				case "convexHull":
					extractContours(true);
					break;
			}
		}
	}

	// 修改extractContours方法，添加凸包处理参数
	private void extractContours(boolean applyConvexHull) {
		// 从纹理数据提取轮廓
		contours = ContourTracerApp.testContourTrace(imageData, true, true, false);

		if (applyConvexHull) {
			ContourTracer.convexHullExtraction(contours);
		}

		contourVerticesList = new ArrayList<>();
		// 将轮廓点转换为屏幕坐标
		for (Contour contour : contours) {
			if (contour.points.size() > 2) {
				float[] vertices = convertContourToVertices(contour);
				contourVerticesList.add(vertices);
			}
		}
		contoursExtracted = true;
	}

	private int[][] extractAndRotateImageDataFromTexture() {
		if (!grassTexture.getTextureData().isPrepared()) {
			grassTexture.getTextureData().prepare();
		}

		Pixmap originalPixmap = grassTexture.getTextureData().consumePixmap();
		int width = originalPixmap.getWidth();
		int height = originalPixmap.getHeight();
		Pixmap rotatedPixmap = new Pixmap(width, height, originalPixmap.getFormat());
		int[][] imageData = new int[height][width];

		// 旋转参数
		double rad = Math.toRadians(rotation);
		double cos = Math.cos(rad);
		double sin = Math.sin(rad);
		double centerX = width / 2.0;
		double centerY = height / 2.0;

		// 同时处理旋转和提取数据
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				// 计算旋转后的源像素位置
				double relX = x - centerX;
				double relY = y - centerY;
				int srcX = (int) (relX * cos - relY * sin + centerX);
				int srcY = (int) (relX * sin + relY * cos + centerY);

				int alpha = 0;
				if (srcX >= 0 && srcX < width && srcY >= 0 && srcY < height) {
					int pixel = originalPixmap.getPixel(srcX, srcY);
					alpha = pixel & 0xff; // 获取alpha通道
					rotatedPixmap.drawPixel(x, y, pixel);
				}
				imageData[height - 1 - y][x] = alpha;
			}
		}

		if (rotatedTexture != null) {
			rotatedTexture.dispose();
		}
		rotatedTexture = new Texture(rotatedPixmap);

		originalPixmap.dispose();
		rotatedPixmap.dispose();

		return imageData;
	}

	private void drawContourPolygons() {
		shapeRenderer.setProjectionMatrix(worldViewport.getCamera().combined);
		shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
		shapeRenderer.setColor(polygonColor);

		for (float[] vertices : contourVerticesList) {
			drawThickPolygonWithRect(vertices, polygonWidth);
		}

		shapeRenderer.end();
	}

	private void drawThickPolygonWithRect(float[] vertices, float width) {
		int pointCount = vertices.length / 2;

		for (int i = 0; i < pointCount; i++) {
			int nextI = (i + 1) % pointCount;
			float x1 = vertices[i * 2];
			float y1 = vertices[i * 2 + 1];
			float x2 = vertices[nextI * 2];
			float y2 = vertices[nextI * 2 + 1];

			// 直接用rectLine绘制加粗线段
			shapeRenderer.rectLine(x1, y1, x2, y2, width);
		}
	}

	private float[] convertContourToVertices(Contour contour) {
		float[] vertices = new float[contour.points.size() * 2];
		float textureWidth = grassTexture.getWidth() * scale;
		float textureHeight = grassTexture.getHeight() * scale;
		float centerX = (worldWidth - textureWidth) / 2;
		float centerY = (worldHeight - textureHeight) / 2;

		float[] offset = new float[2];
		for (int i = 0; i < contour.points.size(); i++) {
			int[] point = contour.points.get(i);
//			int dir = contour.chainCodes.get(i);
//			int norDir = (dir + 6) % 8;
//			offset[0] = offset[1] = 0;
//			if(norDir == 6) {
//				offset[0] = ImageConstants.DIRECTIONS_8[norDir][0]/2f;
//				offset[1] = ImageConstants.DIRECTIONS_8[norDir][1]/2f;
//			}
//			if(norDir == 0) {
//				offset[0] = ImageConstants.DIRECTIONS_8[norDir][0]/2f;
//				offset[1] = ImageConstants.DIRECTIONS_8[norDir][1]/2f;
//			}
			vertices[i * 2] = centerX + (point[0] + 0.5f + offset[0]) * scale;
			vertices[i * 2 + 1] = centerY + (point[1] + 0.5f + offset[1]) * scale;
		}
		return vertices;
	}

	@Override
	public void resize(int width, int height) {
		worldViewport.update(width, height, true);
	}

	@Override
	public void dispose() {
		batch.dispose();
		shapeRenderer.dispose();
		grassTexture.dispose();
	}
}
